package mn.idax.exchange.otc.service.impl;

import mn.idax.exchange.common.CalendarUtil;
import mn.idax.exchange.common.SpringUtils;
import mn.idax.exchange.otc.constant.CommonConstant;
import mn.idax.exchange.otc.domain.CommentShowResultDTO;
import mn.idax.exchange.otc.entity.OTCComment;
import mn.idax.exchange.otc.entity.OTCCommentExample;
import mn.idax.exchange.otc.entity.OTCOrder;
import mn.idax.exchange.otc.enums.CommentEnum;
import mn.idax.exchange.otc.enums.CommentTypeEnum;
import mn.idax.exchange.otc.enums.OrderState;
import mn.idax.exchange.otc.enums.response.CommentResponseEnum;
import mn.idax.exchange.otc.exception.IdaxException;
import mn.idax.exchange.otc.mapper.OTCCommentMapper;
import mn.idax.exchange.otc.mapper.OTCUserMapper;
import mn.idax.exchange.otc.service.FileUrlService;
import mn.idax.exchange.otc.service.OTCCommentService;
import mn.idax.exchange.otc.service.OTCOrderService;
import mn.idax.exchange.otc.service.OTCUserService;
import mn.idax.exchange.otc.util.DateUtils;
import mn.idax.exchange.otc.util.LogUtils;
import mn.idax.exchange.otc.util.NickNameUtils;
import mn.idax.exchange.otc.vo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Create by jack_huang on 2018/8/6
 * 信用评价
 */

@Service
public class OTCCommentServiceImpl implements OTCCommentService{

    @Autowired
    private OTCCommentMapper otcCommentMapper;

    @Autowired
    private OTCOrderService otcOrderService;

    @Autowired
    private OTCUserService otcUserService;

    @Autowired
    private FileUrlService fileUrlService;


    //通过订单号和评论人id查询评论
    @Override
    public OTCComment getCommentByNumAndCommentUserId(String orderNum, Integer userid) {
        OTCCommentExample example = new OTCCommentExample();
        example.createCriteria().andOrdernumEqualTo(orderNum).andCommentuseridEqualTo(userid);
        List<OTCComment> otcComments = otcCommentMapper.selectByExample(example);
        return otcComments.isEmpty() ? null:otcComments.get(0);
    }


    //新增评论
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED,rollbackFor = {RuntimeException.class,Exception.class})
    public Boolean createComment(String orderNum, Integer commentType, String content, Integer userid) throws IdaxException {
        OTCOrder order = otcOrderService.getOrderByOrderNum(orderNum);
        //没有这个订单
        if (order == null){
            LogUtils.warn(this.getClass(), "createCommentOrderNotExist,orderNum " + orderNum);
            throw new IdaxException(CommentResponseEnum.ORDERID_ISNOTEXIST.getRespCode());
        }

        //订单状态必须为已完成 4 时
        if (order.getOrderstate().intValue() != OrderState.STATE_FINISH.getCode().intValue()){
            throw new IdaxException(CommentResponseEnum.ORDERSTATE_NOTSUPPORT.getRespCode());
        }

        //当前用户必须为该笔订单的买家或者卖家
        if (userid.intValue() != order.getSeller().intValue() && userid.intValue() != order.getBuyer().intValue()){
            LogUtils.warn(this.getClass(), "createCommentOrderNonOrder,orderNum " + userid);
            throw new IdaxException(CommentResponseEnum.COMMETN_WITHNOAUTH.getRespCode());
        }

        OTCComment comment = getCommentByNumAndCommentUserId(orderNum,userid);
        //已被评论过
        if (comment != null){
            throw new IdaxException(CommentResponseEnum.COMMENT_ISEXIST.getRespCode());
        }

        OTCComment otcComment = new OTCComment();
        otcComment.setOrdernum(orderNum);
        otcComment.setCommentuserid(userid);
        //买家评价
        if (order.getBuyer().intValue() == userid.intValue()){
            otcComment.setBecommentuserid(order.getSeller());
            otcComment.setTradetype(CommentEnum.COMMENT_BY_BUYER.getCode());
        } else {
            //卖家评价
            otcComment.setBecommentuserid(order.getBuyer());
            otcComment.setTradetype(CommentEnum.COMMENT_BY_SELLER.getCode());// 1 买家 2 卖家
        }
        otcComment.setAdid(order.getAdid());
        otcComment.setCommenttype(commentType);//1 好评 0 中评 -1 差评
        otcComment.setContent(content);
        otcComment.setCommenttime(DateUtils.getCalendarToDate(CalendarUtil.getUTCDate(new Date())));
        otcComment.setIscontent(StringUtils.isNotEmpty(content));//1代表true，0代表false
        otcComment.setIsdelete(false);//是否删除(0-正常 1-删除)
        otcComment.setCreatetime(otcComment.getCommenttime());
        otcComment.setUpdatetime(otcComment.getCommenttime());

        Integer insert = otcCommentMapper.insertSelective(otcComment);
        //评价完更新好评率
        Boolean updateUserGoodRate = otcUserService.addUserGoodRate(otcComment);

        return insert > 0 && updateUserGoodRate;
    }

    //删除评论
    @Override
    public Boolean deleteComment(String orderNum, Integer userid) throws IdaxException {
        OTCComment comment = getCommentByNumAndCommentUserId(orderNum, userid);
        //评论必须存在 包括删除评论的人必须是该笔评论的评论人
        if (comment == null){
            throw new IdaxException(CommentResponseEnum.COMMENT_ISNOTEXIST.getRespCode());
        }
        comment.setIsdelete(true);
        return otcCommentMapper.updateByPrimaryKeySelective(comment) > 0;
    }

    //修改评论
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED,rollbackFor = {RuntimeException.class,Exception.class})
    public Boolean updateCommentLevel(String orderNum, Integer commentType, Integer userid, String content) throws IdaxException {
        OTCComment comment = getCommentByNumAndCommentUserId(orderNum, userid);
        //评论必须存在 包括删除评论的人必须是该笔评论的评论人
        if (comment == null){
            throw new IdaxException(CommentResponseEnum.COMMENT_ISNOTEXIST.getRespCode());
        }
        //用户只能改差评
        if (!comment.getCommenttype().equals(CommentTypeEnum.COMMENT_NEGATIVE.getCode())){
            throw new IdaxException(CommentResponseEnum.COMMENT_CANNOT_UPDATE.getRespCode());
        }
        //评价被删除不能再改
        if (comment.getIsdelete()){
            throw new IdaxException(CommentResponseEnum.DELETED_COMMENT_CANNOT_UPDATE.getRespCode());
        }
        //只能改一次
        if (comment.getUserupdatecount() > 0){
            throw new IdaxException(CommentResponseEnum.COMMETN_ALREADY_UPDATE.getRespCode());
        }

        //只有买广告的人才可以改 kiding
        OTCOrder otcOrder = otcOrderService.getOrderByOrderNum(orderNum);
        if (!userid.equals(otcOrder.getOwner())){
            throw new IdaxException(CommentResponseEnum.CAN_NOT_UPDATE.getRespCode());
        }

        OTCComment oldComment = new OTCComment();
        BeanUtils.copyProperties(comment,oldComment);
        comment.setCommenttype(commentType);
        comment.setContent(content);
        comment.setUserupdatecount(comment.getUserupdatecount() + 1);
        Integer update = otcCommentMapper.updateByPrimaryKeySelective(comment);

        //更新好评率
        Boolean updateUserGoodRate = otcUserService.updateUserGoodRate(oldComment,comment);
        return update > 0 && updateUserGoodRate;
    }

    //评价分页
    @Override
    public CommentShowResultDTO getCommentPage(GetCommentPageDTO getCommentPageDTO) {
        //查询list
        List<CommentPageResultDTO> otcCommentList = otcCommentMapper.getCommentList(getCommentPageDTO);

        //查询 好评 差评 中评 评价有内容 的数量
        UserCommentDTO userCommentDTO = otcCommentMapper.getUserBeCommentNumbers(getCommentPageDTO.getUserId());

        if (otcCommentList.isEmpty()){
            List<CommentPageListDTO> commentPageList = new ArrayList<>();
            return new CommentShowResultDTO(commentPageList,userCommentDTO,0);
        }
        List<CommentPageListDTO> commentPageListDTOS = getCommentResultList(otcCommentList);
        //查询total
        Integer total = otcCommentMapper.getCommentTotal(getCommentPageDTO);

        return new CommentShowResultDTO(commentPageListDTOS,userCommentDTO,total);
    }


    //封装分页返回list参数
    private List<CommentPageListDTO> getCommentResultList(List<CommentPageResultDTO> otcCommentList) {
        List<CommentPageListDTO> commentPageList = new ArrayList<>();
        //
        String beCommentNickName = NickNameUtils.concatNickName(otcCommentList.get(0).getBeCommentNickName(),otcCommentList.get(0).getBeEmail());
        for (CommentPageResultDTO comment : otcCommentList) {
            CommentPageListDTO commentPage = new CommentPageListDTO();
            //这里展示的类型和广告的类型是反的
            String type = comment.getTradeType() == 1 ? SpringUtils.getMessage("message." + CommentEnum.COMMENT__SELL.getMsg())
                    : SpringUtils.getMessage("message." + CommentEnum.COMMENT_BUY.getMsg());
            commentPage.setTitle(beCommentNickName.concat(" ").concat(type).concat(SpringUtils.getMessage("message."+CommonConstant.DIGITAL_ASSETS)));//天王盖地虎 出售数字资产
            commentPage.setCommentNickName(NickNameUtils.concatNickName(comment.getCommentNickName(),comment.getEmail()));
            if (comment.getCommentType().intValue()== CommentTypeEnum.COMMENT_GOOD.getCode().intValue()){
                commentPage.setCommentType(SpringUtils.getMessage("message."+CommentTypeEnum.COMMENT_GOOD.getMsg()));
                commentPage.setCommenterType(comment.getCommentType());

            } else  if (comment.getCommentType().intValue() == CommentTypeEnum.COMMENT_MEDIUM.getCode().intValue()){
                commentPage.setCommentType(SpringUtils.getMessage("message."+CommentTypeEnum.COMMENT_MEDIUM.getMsg()));
                commentPage.setCommenterType(comment.getCommentType());

            } else {
                commentPage.setCommentType(SpringUtils.getMessage("message."+CommentTypeEnum.COMMENT_NEGATIVE.getMsg()));
                commentPage.setCommenterType(comment.getCommentType());
            }


            commentPage.setContent(StringUtils.isEmpty(comment.getContent()) ? SpringUtils.getMessage("message."+CommonConstant.COMMENTCONTENTISEMPTY) : comment.getContent());
            commentPage.setCommentTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(comment.getCreateTime()));
            commentPage.setIconUrl(fileUrlService.dealFileUrlAddress(comment.getIconUrl()));
            commentPage.setCommenterTradeType(comment.getTradeType());
            commentPage.setIsBusinesser(comment.getIsBusinesser() == 0 ? false : true);
            commentPageList.add(commentPage);
        }
        return commentPageList;
    }

    //订单详情中的评论信息
    @Override
    public OrderDetailCommentDTO getOrderDetailCommentInfo(Integer userid, String orderNum) {
        OTCCommentExample example = new OTCCommentExample();
        example.createCriteria().andOrdernumEqualTo(orderNum).andCommentuseridEqualTo(userid);

        List<OTCComment> otcCommentList = otcCommentMapper.selectByExample(example);
        if (otcCommentList.isEmpty()){
            return new OrderDetailCommentDTO();
        }


        return new OrderDetailCommentDTO(otcCommentList.get(0).getCommenttype(),
                StringUtils.isEmpty(otcCommentList.get(0).getContent()) ? "" : otcCommentList.get(0).getContent(),otcCommentList.get(0).getUserupdatecount());
    }

    //个人中心 我收到的所有评价
    @Override
    public List<UserBeCommentResult> getOthersCommentMe(Integer userId) {
        List<UserBeCommentDTO> list = otcCommentMapper.getOthersCommentMe(userId);
        if (list.isEmpty()){
            return new ArrayList<>();
        }
        return getOthersCommentMeResult(list);
    }

    @Override
    public List<OTCComment> getCommentByOrderNum(String orderNum) {

        OTCCommentExample otcCommentExample = new OTCCommentExample();
        otcCommentExample.createCriteria().andOrdernumEqualTo(orderNum);
        return otcCommentMapper.selectByExample(otcCommentExample);
    }

    private List<UserBeCommentResult> getOthersCommentMeResult(List<UserBeCommentDTO> list) {
        List<UserBeCommentResult> results = new ArrayList<>();
        for (UserBeCommentDTO userBeCommentDTO : list) {
            UserBeCommentResult userBeCommentResult = new UserBeCommentResult();
            userBeCommentResult.setContent(StringUtils.isEmpty(userBeCommentDTO.getContent()) ?  SpringUtils.getMessage("message."+CommonConstant.COMMENTCONTENTISEMPTY) : userBeCommentDTO.getContent());
            userBeCommentResult.setCreateTime(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(userBeCommentDTO.getCreateTime()));
            userBeCommentResult.setNickName(StringUtils.isEmpty(userBeCommentDTO.getNickName()) ?
                    NickNameUtils.concatNickName(userBeCommentDTO.getNickName(),userBeCommentDTO.getEmail()) : userBeCommentDTO.getNickName());
            userBeCommentResult.setCommentType(userBeCommentDTO.getCommentType());
            userBeCommentResult.setIconUrl(fileUrlService.dealFileUrlAddress(userBeCommentDTO.getIconUrl()));
            results.add(userBeCommentResult);
        }
        return results;
    }


}
